﻿using System;
using System.Linq.Expressions;

namespace DynamicMocker
{
	public class Mock<T> where T : class
	{
		private readonly ObjectWrapper _mockedObject;

		public Mock(params object[] constructorArguments)
		{
			_mockedObject = new ObjectWrapper(typeof(T), constructorArguments);
		}

		public dynamic Object
		{
			get
			{
				return _mockedObject;
			}
		}

		/// <summary>
		/// Fake method initialization
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="wrappedMethod"></param>
		/// <returns></returns>
		public MethodWrapper Setup<TResult>(Expression<Func<T, TResult>> wrappedMethod)
		{
			return SetupFake((MethodCallExpression)wrappedMethod.Body);
		}

		private MethodWrapper SetupFake(MethodCallExpression methodInfo)
		{
			var methodName = methodInfo.Method.Name;
			var methodWrapper = new MethodWrapper
														{
															OriginalMethodInfo = methodInfo
														};
			_mockedObject.AddFakeMethod(methodName, methodWrapper);
			return methodWrapper;
		}

		public MethodWrapper Setup(Expression<Action<T>> wrappedAction)
		{
			return SetupFake((MethodCallExpression)wrappedAction.Body);
		}

		public bool Verify()
		{
			return _mockedObject.Verify();
		}
	}
}
